package universum.bi;

import universum.engine.topology.TorusTopology;
import universum.util.ioUtility;

import java.util.*;

public abstract class CustomBeing implements IBeing {
    protected Map<Integer, Float> customArgs;
    protected ioUtility io = ioUtility.getInstance();
    protected TorusTopology topology = TorusTopology.getInstance();

    //custArgEnum tmp;
    protected CustomBeing() {
        //  customArgs = new HashMap<Integer, Float>();        
    }

    public final void reinit(UserGameInfo info) {
        customArgs = new HashMap<Integer, Float>();
        reinit(info.kind, info.maxTurns);
        Float argValue;
        Map<String, Integer> customArgNamesMap = getCustomArgsNames();
        for (Map.Entry<String, Integer> pair : customArgNamesMap.entrySet()) {
            argValue = info.customArgs.containsKey(pair.getKey()) ? Float.valueOf(info.customArgs.get(pair.getKey())) : getCustomArgDefaultValue(pair.getValue());
            customArgs.put(pair.getValue(), argValue);
        }
    }

    protected List<Location> getEquallySpacedLocationsSubset(List<Location> source, Location center, int distance) {
        List<Location> result = new ArrayList<Location>();
        //ioUtility.getInstance().writeInfo("hello from custom");
        //Statistics.getInstance().addReport("");        
        for (Location p : source) if (distance == Math.abs(topology.distance(p, center))) result.add(p);
        return result;
    }

    protected abstract void reinit(GameKind gameKind, int maxTurns);

    protected abstract Map<String, Integer> getCustomArgsNames();

    protected abstract Float getCustomArgDefaultValue(int i);

    protected List<Location> filterCellsExcluding(List<Location> sourceList, List<Location> exceptList) {
        List<Location> result = new ArrayList<Location>();
        for (Location cell : sourceList) if (!exceptList.contains(cell)) result.add(cell);
        return result;
    }
    protected TreeSet<Location> filterCellsExcluding(TreeSet<Location> sourceList, TreeSet<Location> exceptList) {
        TreeSet<Location> result = new TreeSet<Location>(Location.LocationComparator);
        for (Location cell : sourceList) if (!exceptList.contains(cell)) result.add(cell);
        return result;
    }
    protected List<Location> filterCellsExcludingR(List<Location> sourceList, List<Location> exceptList) {
        List<Location> result = new ArrayList<Location>(sourceList);
        for (Location cell : exceptList) result.remove(cell);
        return result;
    }

    protected List<Location> filterCellsIncluding(List<Location> sourceList, List<Location> includeList)
    {
        List<Location> result = new ArrayList<Location>();
        for (Location cell : sourceList) if (includeList.contains(cell)) result.add(cell);
        return result;
    }
    /*protected List<Location> joinList( List<Location> list1, List<Location> list2)
    {
        List<Location> result = new ArrayList<Location>(list1);
    } */
}
